package com.lenovo.lcdm.type.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.lenovo.lcdm.common.enums.CommonMsgEnum;
import com.lenovo.lcdm.common.enums.DeleteFlagEnum;
import com.lenovo.lcdm.common.exception.BusinessException;
import com.lenovo.lcdm.common.exception.ServiceException;
import com.lenovo.lcdm.type.util.ContextUtil;
import com.lenovo.lcdm.type.dto.AttributeGroupDTO;
import com.lenovo.lcdm.type.entity.TypeAttributeGroup;
import com.lenovo.lcdm.type.entity.TypeAttributeGroupAttribute;
import com.lenovo.lcdm.type.entity.TypeLocalAttribute;
import com.lenovo.lcdm.type.entity.TypeLocalAttributeLink;
import com.lenovo.lcdm.type.mapper.TypeAttributeGroupMapper;
import com.lenovo.lcdm.type.service.TypeAttributeGroupAttributeService;
import com.lenovo.lcdm.type.service.TypeAttributeGroupService;
import com.lenovo.lcdm.type.service.TypeLocalAttributeLinkService;
import com.lenovo.lcdm.type.service.TypeLocalAttributeService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;

import java.time.LocalDateTime;
import java.util.List;
import java.util.stream.Collectors;

/**
* @author xujing30
* @description 针对表【type_attribute_group】的数据库操作Service实现
* @createDate 2024-01-17 16:56:58
*/
@Service
public class TypeAttributeGroupServiceImpl extends ServiceImpl<TypeAttributeGroupMapper, TypeAttributeGroup>
    implements TypeAttributeGroupService {

    @Autowired
    private TypeAttributeGroupAttributeService attributeGroupAttributeService;

    @Autowired
    private TypeLocalAttributeLinkService typeLocalAttributeLinkService;

    @Autowired
    private TypeLocalAttributeService localAttributeService;

    @Override
    public void saveGroup(AttributeGroupDTO attributeGroupDTO) {
        TypeAttributeGroup attributeGroup = null;
        if(attributeGroupDTO.getId() == null) {
            attributeGroup = new TypeAttributeGroup();
            attributeGroup.setCreateTime(LocalDateTime.now());
            attributeGroup.setCreator(ContextUtil.getCurrentUser());
        }else{
            attributeGroup = this.getById(attributeGroupDTO.getId());
            if(attributeGroup == null){
                throw new ServiceException("Group Id cannot be empty!" ,CommonMsgEnum.FAIL.getCode());
            }

        }
        // 类型下不能创建同名组可以由前端判断，在此不做判断
        BeanUtils.copyProperties(attributeGroupDTO, attributeGroup);
        attributeGroup.setModifyTime(LocalDateTime.now());
        attributeGroup.setModifier(ContextUtil.getCurrentUser());
        attributeGroup.setDeleted(DeleteFlagEnum.NO.getValue());
        attributeGroup.setObjectClass(attributeGroup.getClass().getName());
        this.saveOrUpdate(attributeGroup);
    }

    @Override
    public void deleteGroup(Long groupId) {
        LambdaQueryWrapper<TypeAttributeGroupAttribute> qw = new LambdaQueryWrapper<>();
        qw.in(TypeAttributeGroupAttribute::getGroupId, groupId);
        List<TypeAttributeGroupAttribute> groupAttributes = attributeGroupAttributeService.list(qw);
        if (CollectionUtils.isEmpty(groupAttributes)) {
            this.removeById(groupId);
        } else {
            throw new BusinessException("You cannot delete a group associated with attributes, please delete these attributes or change them to other groups first!", CommonMsgEnum.FAIL.getCode());
       }
    }

    @Override
    public void batchDelAttributesOfGroup(List<Long> localAttributeIds) {
        if(CollectionUtils.isEmpty(localAttributeIds)){
            return;
        }
        //todo check 属性是否已有实际使用值
        
        LambdaQueryWrapper<TypeAttributeGroupAttribute> attributeGroupAttributeQw = new LambdaQueryWrapper<>();
        attributeGroupAttributeQw.in(TypeAttributeGroupAttribute::getLocalAttributeId, localAttributeIds);
        attributeGroupAttributeService.remove(attributeGroupAttributeQw);

        // 删除TypeLocalAttributeLink
        LambdaQueryWrapper<TypeLocalAttributeLink> typeLocalAttributeLinkQw = new LambdaQueryWrapper<>();
        typeLocalAttributeLinkQw.in(TypeLocalAttributeLink::getLocalAttributeId, localAttributeIds);
        typeLocalAttributeLinkService.remove(typeLocalAttributeLinkQw);

        // 删除TypeLocalAttributeSort

        // 删除本地属性
        localAttributeService.removeBatchByIds(localAttributeIds);
    }

    @Override
    public void changeGroupForAttributes(List<Long> localAttributeIds, Long groupId, Long typeId) {
        if(ObjectUtils.isEmpty(getById(groupId))){
            throw new ServiceException("To group not exist." ,CommonMsgEnum.FAIL.getCode());
        }

        //要change的globalAttribute
        List<TypeLocalAttribute> fromLocalAttributes = localAttributeService.listByIds(localAttributeIds);
        if(CollectionUtils.isEmpty(fromLocalAttributes)){
            return;
        }
        List<Long> fromGlobalAttributeIds = fromLocalAttributes.stream().map(TypeLocalAttribute::getGlobalAttributeId).collect(Collectors.toList());

        //检查另外一个组下是否有相同的globalAttributeId
        LambdaQueryWrapper<TypeAttributeGroupAttribute> attributeGroupAttributeQw = new LambdaQueryWrapper<>();
        attributeGroupAttributeQw.eq(TypeAttributeGroupAttribute::getGroupId, groupId).eq(TypeAttributeGroupAttribute::getTypeId, typeId);
        List<TypeAttributeGroupAttribute> toGroupAttributes = attributeGroupAttributeService.list(attributeGroupAttributeQw);

        if(!CollectionUtils.isEmpty(toGroupAttributes)){
            List<Long> toLocalAttributeIds = toGroupAttributes.stream().map(TypeAttributeGroupAttribute::getLocalAttributeId).collect(Collectors.toList());
            List<TypeLocalAttribute> toLocalAttributes = localAttributeService.listByIds(toLocalAttributeIds);
            List<Long> toGlobalAttributeIds = toLocalAttributes.stream().map(TypeLocalAttribute::getGlobalAttributeId).collect(Collectors.toList());

            if(CollectionUtils.containsAny(toGlobalAttributeIds, fromGlobalAttributeIds)){
                throw new BusinessException("There are same global attribute in the group.", CommonMsgEnum.FAIL.getCode());
            }
        }
        //更新group和local attribute关联
        attributeGroupAttributeService.lambdaUpdate().set(TypeAttributeGroupAttribute::getGroupId, groupId).set(TypeAttributeGroupAttribute::getModifier, ContextUtil.getCurrentUser()).set(TypeAttributeGroupAttribute::getModifyTime, LocalDateTime.now()).eq(TypeAttributeGroupAttribute::getTypeId, typeId).in(TypeAttributeGroupAttribute::getLocalAttributeId, localAttributeIds).update();

    }

    @Override
    public List<TypeAttributeGroupAttribute> queryGroupAttribute(List<Long> groupIds) {
        LambdaQueryWrapper<TypeAttributeGroupAttribute> attributeGroupAttributeQw = new LambdaQueryWrapper<>();
        attributeGroupAttributeQw.in(TypeAttributeGroupAttribute::getGroupId, groupIds).eq(TypeAttributeGroupAttribute::getDeleted, DeleteFlagEnum.NO.getValue());
        return attributeGroupAttributeService.list(attributeGroupAttributeQw);
    }
}




